from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.shortcuts import render

# Create your views here.
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework import viewsets, mixins
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from users.models import User
from users.serilaizers import ChekUsernameSerilizer, CheckMobileSerilizer, UserRegisterSerializer, RestPwdSerializer, \
    UserDetailSerializer, UserUpateSerializer
from verifications.serializers import CheckImageCodeSerializer

User = get_user_model()


class UsernameCountView(GenericAPIView):
    serializer_class = ChekUsernameSerilizer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        username = serializer.validated_data["username"]
        count = User.objects.filter(username=username).count()
        data = {
            'username': username,
            'count': count
        }
        return Response(data, status=status.HTTP_200_OK)


class MobileCountView(GenericAPIView):
    serializer_class = CheckMobileSerilizer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        mobile = serializer.validated_data["mobile"]
        count = User.objects.filter(mobile=mobile).count()
        data = {
            'mobile': mobile,
            'count': count
        }
        return Response(data, status=status.HTTP_200_OK)


class CustomBackend(ModelBackend):
    """
    自定义用户认证
    """

    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username=username) | Q(mobile=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None


class UserViewset(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
    """
    用户viewsets
    """
    serializer_class = UserRegisterSerializer
    queryset = User.objects.all()

    def get_permissions(self):
        self.permission_classes = []
        if self.action == "retrieve" or self.action == "update":
            self.permission_classes.append(IsAuthenticated)

        return [permission() for permission in self.permission_classes]

    def get_serializer_class(self):
        if self.action == "create":
            return UserRegisterSerializer
        elif self.action == "update":
            return UserUpateSerializer
        else:
            return UserDetailSerializer

    def get_object(self):
        return self.request.user

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # payload = jwt_payload_handler(user)
        # token = jwt_encode_handler(payload)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_200_OK, headers=headers)


class SMSCodeTokenViewset(mixins.CreateModelMixin, viewsets.GenericViewSet):
    serializer_class = CheckImageCodeSerializer

    def create(self, request, *args, **kwargs):
        # 校验图片验证码
        # 根据account查询User兑现
        # 根据User对象的手机号生成access_token
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        account = serializer.validated_data["account"]
        user = User.objects.get(Q(username=account) | Q(mobile=account))

        if user is None:
            return Response({
                "account": "用户不存在"
            }, status=status.HTTP_404_NOT_FOUND)

        access_token = user.generate_send_sms_code_token()

        return Response({
            "account": account,
            "mobile": user.mobile,
            "access_token": access_token
        }, status=status.HTTP_200_OK)


class ResetPwdView(mixins.UpdateModelMixin, GenericAPIView):
    serializer_class = RestPwdSerializer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        mobile = serializer.validated_data["mobile"]
        password = serializer.validated_data["password"]

        user = User.objects.get(mobile=mobile)
        user.password = password

        user.save()

        return Response({
            "message": "密码修改成功，请重新登陆"
        }, status=status.HTTP_200_OK)

